<?php
namespace xmltool;

use App\Models\Review\ActivityFlow;
use XMLReader;
use XmlTool\Listener\ActivityFormInsertListener;
use XmlTool\Listener\ActivityFormUpdateListener;
use XmlTool\Listener\ActivityInsertListener;
use XmlTool\Listener\ActivityUpdateListener;

class Xml2Object{
    private static $instance;
    private $document;
    private $flowDoc;
    const FORMXML_SAVE_PATH="../xmltool/forms/";
    const TABLEXML_SAVE_PATH="../xmltool/tables/";
    private function __construct()
    {
        
    }
    public static function getInstance(){
        if(!self::$instance)
        self::$instance=new self();
        return self::$instance;
    }
    private function nodeValue($v){
        return empty($v)?$v:((array)$v)[0];
    }
    public function parse(string $file_path){
        $this->document=$v=null;
        if(file_exists($file_path)){
            $root=simplexml_load_file($file_path) or die('xml file exception');
            if($root){
                $rootName=$root->getName();
                $insert=$root->insert;
                $update=$root->update;
                $listener=$root->listener;
                $v=[$rootName=>[
                    'insert'=>[],
                    'update'=>[],
                    'listener'=>[],
                ]];
                $cds=$insert->children();
                foreach($cds as $k=>$v1){
                    $key=$v1['key']??null;
                    $type=$v1['type']??null;
                    $auto=$v1['auto']??null;
                    $default=$v1['default']??null;
                    $v[$rootName]['insert'][$k]['key']=$this->nodeValue($key);
                    $v[$rootName]['insert'][$k]['type']=$this->nodeValue($type);
                    $v[$rootName]['insert'][$k]['auto']=$this->nodeValue($auto);
                    $v[$rootName]['insert'][$k]['default']=$this->nodeValue($default);
                }
                $cds=$update->children();
                foreach($cds as $k=>$v1){
                    $key=$v1['key']??null;
                    $type=$v1['type']??null;
                    $auto=$v1['auto']??null;
                    $default=$v1['default']??null;
                    $v[$rootName]['update'][$k]['key']=$this->nodeValue($key);
                    $v[$rootName]['update'][$k]['type']=$this->nodeValue($type);
                    $v[$rootName]['update'][$k]['auto']=$this->nodeValue($auto);
                    $v[$rootName]['update'][$k]['default']=$this->nodeValue($default);
                }
                $cds=$listener->children();
                foreach($cds as $k=>$v1){
                    $when=$v1['when']??null;
                    $action=$v1['action']??null;
                    $v[$rootName]['listener'][$this->nodeValue($when)]=['action'=>$this->nodeValue($action)];
                }
            }
        }
        $this->document=&$v;
        return $v;
    }
    public function parseFlow(string $file_path){
        $this->flowDoc=$doc=new ActivityFlow;
        if(file_exists($file_path)){
            $root=simplexml_load_file($file_path) or die('xml file exception');
            $rootStepList=$root->children();
            foreach($rootStepList as $k=>$v){
                $idx=$v['idx'];
                foreach($v->children() as $k1=>$v1){
                    $idx1=$v['idx'];
                    $depend=$v['depend'];
                }
            }
        }
        $this->document=&$v;
        return $v;
    }
    public function getDocument(){
        return $this->document;
    }
    public static function emitEvent($action,$model){
        $className=null;
        $prefix=null;
        switch($action){
            case "ActivityInsertListener":
            $className=ActivityInsertListener::class;
            break;
            case "ActivityUpdateListener":
            $className=ActivityUpdateListener::class;
            $prefix="__keys";
            break;
            case "ActivityFormInsertListener":
            $className=ActivityFormInsertListener::class;
            break;
            case "ActivityFormUpdateListener":
            $className=ActivityFormUpdateListener::class;
            $prefix="__keys";
            break;
            default:
            break;
        }
        $obj=new $className($model);
        return dispatch($obj);
    }
}
